import {autoSerialize} from "../../serializeDecorator";
import PlayerState from "../playerAgent";
import {SubPhaseName, TableSubPhaseBase, timeLeft} from "./base";
import ms = require("ms")
import {random} from 'lodash'

export class QuizPhase extends TableSubPhaseBase {
  timer: NodeJS.Timer
  private robotTimer: NodeJS.Timer;

  @autoSerialize
  private isFreeze: boolean = false

  @autoSerialize
  private freezeAt: number = 0

  private freezeDuration: number = ms('3s')

  private freezeTimer: NodeJS.Timer;

  name(): SubPhaseName {
    return 'QuizPhase';
  }

  resume({quizStartAt}) {
    if (quizStartAt > 0) {
      this.table.quizStartAt = quizStartAt || 0

      this.timer = setTimeout(() => {
        this.autoSubmit()
      }, timeLeft(this.table.quizStartAt, this.table.quizStartTimeout))
    } else {
      this.onEntry()
    }
  }

  onEntry() {
    this.isFreeze = false
    this.freezeAt = 0
    this.table.initAnswerState()
    this.table.initPlayerState()
    const quizData = this.table.getCurrentQuizData()

    this.table.quizStartAt = Date.now()
    this.table.state = 'quizStart'
    this.table.broadcast('game/quizStart', {
      question: quizData.quiz.question,
      options: quizData.quiz.options,
      current: quizData.index, total: quizData.total,
      end: this.table.quizStartAt + this.table.quizStartTimeout
    })

    this.timer = setTimeout(() => {
      this.autoSubmit()
    }, this.table.quizStartTimeout)

    this.robotTimer = setTimeout(() => {
      this.robotAction()
    }, random(ms('5s'), ms('6s')))

  }


  private robotAction() {

    this.table.players.filter((player) => player._id.startsWith('robot'))
      .forEach((player) => {

        const quizData = this.table.getCurrentQuizData()
        let index = 0
        if (Math.random() > 0.4) {
          index = quizData.quiz.options.indexOf(quizData.quiz.answer)
        } else {
          index = random(0, quizData.quiz.options.length - 1)
        }

        this.onPlayerSubmitAnswer(player, {index})
      })

  }

  private autoSubmit() {

    this.table.players.forEach(p => {

      if (!this.table.isAnswered(p))
        this.table.recordPlayerQuit(p)
    })

    this.freezeThenLeave()
  }

  onPlayerSubmitAnswer(player: PlayerState, {index}: { index: number }) {
    const table = this.table

    if (this.isFreeze) {
      player.sendMessage('game/submitAnswerReply', {ok: false, right: false, info: '答题时间已过,不能答题'})
    }

    if (table.isAnswered(player)) {
      player.sendMessage('game/submitAnswerReply', {ok: false, right: false, info: '你已经答了本题'})
      return
    }

    player.myAnswerIndex = index
    if (table.isRightAnswer(index)) {
      player.myAnswerIsRight = true
      player.sendMessage('game/submitAnswerReply', {ok: true, right: true})
    } else {
      player.myAnswerIsRight = false
      player.sendMessage('game/submitAnswerReply', {ok: true, right: false})
    }

    table.recordPlayerAnswer(player, {index})

    if (table.isAllAnswered()) {
      this.freezeThenLeave()
    }

  }

  private freezeThenLeave() {
    clearTimeout(this.timer)
    this.isFreeze = true
    this.freezeAt = Date.now()

    const table = this.table
    table.showAllAnswerInfo();
    const quizResult = table.players.map((p, index) => {
      const quizScore = table.currentQuizScore(p)
      p.score += quizScore
      return {
        index,
        quizScore,
        total: p.score
      }
    })

    this.table.broadcast("game/quizOver", {quizResult})

    this.freezeTimer = setTimeout(() => {
      this.table.nextPhase()
    }, this.freezeDuration)

  }

  onLeave() {
    clearTimeout(this.timer)
    clearTimeout(this.robotTimer)
    clearTimeout(this.freezeTimer)
    const table = this.table

    table.nextQuiz()
    table.state = 'quizOver'


  }
}
